package com.itheima.thread.create.demo03;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * 创建多线程的第三种方式
 *
 *  jdk1.5以后，给我们提供了一个接口Callable，我们可以使用这个接口来实现多线程；在该接口中存在一个方法： V call​()
 *  这个方法和我们Runnable接口中run方法( void run​() )相比较有什么特点？call方法存在返回值，因此可以把这个Callable接口看做是Runnable接口的增强版
 *
 *  如果说后期，我们然某一个线程去执行了某一段代码，而我们还需要去获取这个线程所执行的代码的返回结果，那么我们就需要使用Callable接口来实现了；
 *
 *  这个Callable接口怎么使用呢？是否和Runnable接口的使用方式是一样的呢？ Runnable接口的使用，就是我们创建了一个类，让其去实现了这个Runnable接口，
 *  然后重写了run方法，然后创建了我们这个类的对象，然后在创建Thread类的对象，把我们所创建的对象作为Thread类的构造方法参数进行传递。之所以可以传递
 *  Runnable接口的子类对象，原因是因为在Thread类中定义了这样的构造方法：Thread​(Runnable target)
 *
 *  这个Thread类中有没有定义接收一个Callable类型的参数的构造方法呢？没有 ，因此这个Callable接口的使用和Runnable有所不同。
 *
 *  怎么去使用呢？我们需要借助于FutureTask
 *
 * 实现步骤：
 *
 * 1. 创建一个类实现Callable接口，并重写call方法
 * 2. 创建Callable实现类的对象
 * 3. 创建FutureTask对象，把第二步创建的对象作为参数进行传递              public FutureTask​(Callable<V> callable)
 * 4. 创建Thread对象，把第三步创建的FutureTask对象作为传递进行传递
 * 5. 调用start方法启动线程
 * 6. 调用FutureTask对象的get方法获取线程执行结果
 *
 * 需求：开启一个线程计算1-100之和。
 *
 */
public class ThreadDemo01 {

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        // 创建Callable实现类的对象
        MyCallable myCallable = new MyCallable() ;

        // 创建FutureTask对象，把第二步创建的对象作为参数进行传递: public FutureTask​(Callable<V> callable)
        FutureTask futureTask = new FutureTask(myCallable) ;

        // 创建Thread对象，把第三步创建的FutureTask对象作为传递进行传递
        Thread thread = new Thread(futureTask) ;

        // 调用start方法启动线程
        thread.start();

        // 调用FutureTask对象的get方法获取线程执行结果
        Integer result = (Integer) futureTask.get();
        System.out.println(result);

    }

}


























